package com.qch;

import com.qch.handler.ServiceLoader;
import com.qch.handler.UserHandler;
import com.qch.json.JSONSerializer;
import com.qch.json.RpcDecoder;
import com.qch.json.RpcEncoder;
import com.qch.json.RpcRequest;
import com.qch.service.UserService;
import com.qch.service.UserServiceImpl;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * @Author qch
 * @Date 2021/1/27
 */
@SpringBootApplication
public class ServerBoot {
    public static void main(String[] args) throws InterruptedException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        SpringApplication.run(ServerBoot.class, args);
        startServer("127.0.0.1",8999);
    }

    //创建一个启动服务的代码
    public static void startServer(String ip,int port) throws InterruptedException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //创建两个线程池对象
        //创建服务端启动引导对象
        //配置启动引导类
        //配置端口
        // 获取接口实现类并执行方法
     /*   RpcRequest rpcRequest=new RpcRequest();
        rpcRequest.setClassName("com.qch.service.UserService");
        rpcRequest.setMethodName("sayHello");
        rpcRequest.setParameterTypes(new Class[]{String.class});
        rpcRequest.setParameters(new String[]{"dd"});
        ServiceLoader serviceLoader=new ServiceLoader();
        Map<String, UserService> map = serviceLoader.getBeansOfType(UserService.class);
        for(String key:map.keySet()){//keySet获取map集合key的集合  然后在遍历key即可
            int lastDot = rpcRequest.getClassName().lastIndexOf(".");
            String interfaceName = rpcRequest.getClassName().substring(lastDot+1).toLowerCase();
            String keyLower=key.toLowerCase();
            if(keyLower.contains(interfaceName))
            {
                Method method = map.get(key).getClass().getMethod(rpcRequest.getMethodName(),  rpcRequest.getParameterTypes()[0]); // 此时获得了add方法
                Object invoke = method.invoke(map.get(key), rpcRequest.getParameters()[0]);
                //map.get(key).sayHello("ss");
            }
        }
       // String result = map.get("userServiceImpl").sayHello("ss");*/
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        ChannelPipeline pipeline = nioSocketChannel.pipeline();
                       pipeline.addFirst(new StringEncoder());
                        //pipeline.addLast(new StringDecoder());
                       //pipeline.addFirst( new RpcEncoder(RpcRequest.class, new JSONSerializer()));
                       pipeline.addLast( new RpcDecoder(RpcRequest.class, new JSONSerializer()));
                        //把自定义chanelhandler添加到通道中
                        pipeline.addLast(new UserHandler());
                    }
                });
        serverBootstrap.bind(8999).sync();
    }
}
